/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package org.ejb.modelo;

import java.awt.Image;
import java.io.File;
import java.util.ArrayList;

import org.ejb.modelo.Nivel.TipoNivel;

/**
 * Esta clase representa un juego creado. Cada juego contiene la siguiente información:
 *              1- Metainformación: Información como el título, la imágen que representa la portada y una música.
 *              2- Lista de Escenas
 * @author Hobbes
 *
 */
public class Juego {

        
        //Variables generales del juego.
        ArrayList<Nivel> listaEscenas;          //Es la ensencia del juego, crear pantallas y conectarlas entre si.
        String nombre;                                          //Cada juego debe tener un nombre con el que darse a conocer.
        Image splash;                                           //Y una imágen como portada para ser reconocído.
        File bso;                                                       //Además de una banda sonora.
        String desc;                                            //Descripción del juego.
        int n;
        
        //Variables internas para el control
        
        public Juego(){
            n=0;
            listaEscenas=new ArrayList<Nivel>();
        }
        
        /**
         * Constructor para el objeto juego, inicia las variables internas mínimas.
         * @param nombre
         */
        public Juego(String nombre){
                n=0;
                listaEscenas=new ArrayList<Nivel>();
                this.nombre=nombre;
        }

        /**
         * Devuelve el nombre del juego.
         * @return String con el nombre del juego.
         */
        public String getNombre() {
                return nombre;
        }

        /**
         * Cambia el nombre del juego por el pasado por parametro
         * @param nombre Nuevo nombre del juego.
         */
        public void setNombre(String nombre) {
                this.nombre = nombre;
        }

        /**
         * Toma la imagen de representación del juego.
         * @return
         */
        public Image getSplash() {
                return splash;
        }

        /**
         * Cambia la imagen de representación del juego.
         * @param splash Nueva imagen del juego.
         */
        public void setSplash(Image splash) {
                this.splash = splash;
        }

        /**
         * Obtiene la música de fondo que se ejecuta en bucle para un juego.
         * @return      Archivo de audio.
         */
        public File getBso() {
                return bso;
        }

        /**
         * Cambia el archivo de audio de
         * @param bso Archivo de audio (puede ser midi/wav)
         */
        public void setBso(File bso) {
                this.bso = bso;
        }
        
        /**
         * Guarda la descripción que se le haya dado al juego.
         * @param desc  Descripción del juego "string".
         */
        public void setDescp(String desc) {
                this.desc=desc;         
        }
        
        /**
         * Devuelve la descripción del juego.
         * @return String con la descripción.
         */
        public String getDescp(){
                return desc;
        }
        
        /**
         * Añades aquí las escenas al juego, para mejor control de la integridad, el arrayList se controla mediante un par de métodos.
         * @param e Nuevo Nivel (el último creado), listo para ser rellenado.
         */
        public Nivel nuevoNivel(){
                n++;
                Nivel nivel;
                if(numNivel()==0){
                        nivel=new Nivel(TipoNivel.Inicio);
                }else{
                        nivel= new Nivel(TipoNivel.Medio);
                }
                listaEscenas.add(nivel);
                nivel.setNumero(n);
                return nivel;
        }
        
        /**
         * Devuelve el número de niveles que tiene el juego.
         * @return Número de escenas que componen el juego.
         */
        public int numNivel(){
                return listaEscenas.size();
        }
        
        /**
         * Elimina un nivel del juego y todas las referencias a este nivel desde otros niveles.
         * @param n     Id del nivel a eliminar.
         */
        public void eliminarNivel(Nivel n){
                eliminarConexiones(n);
                listaEscenas.remove(n);
        }
        
        /**
         * Elimina las referencias al id de nivel indicado.
         * @param n     Id del nivel indicado.
         */
        private void eliminarConexiones(Nivel n){
                int num=n.getNumero();
                for(int i=0; i<listaEscenas.size();i++){
                        Nivel aux=listaEscenas.get(i);
                        for(int j=0;j<aux.numEventos();j++){
                                if(aux.getEvento(j).getConexion()==num){
                                        aux.getEvento(j).setConexion(0);
                                }
                        }
                }
        }
        
        /**
         * Da la lista de nombres de los niveles para los comboBox
         * @param n Nivel al que no se debe hacer referencia.
         * @return      Array con los nombres.
         */
        public String[] tomarNiveles(Nivel n){
                String[] niveles=new String[listaEscenas.size()];
                niveles[0]="0 Ninguno";
                int j=1;
                for(int i=0;i<listaEscenas.size();i++){
                        if(listaEscenas.get(i)!=n){
                                niveles[j]=listaEscenas.get(i).getNumero()+" "+listaEscenas.get(i).getNombre();
                                j++;
                        }
                }
                return niveles;
        }
        
        /**
         * Da una lista de id referencias a los niveles. Para los comboBox.
         * @param n Nivel que se debe discriminar
         * @return
         */
        public int[] tomarNumNiveles(Nivel n) {
                int[] numNivel=new int[listaEscenas.size()];
                numNivel[0]=0;
                int j=1;
                for(int i=0;i<listaEscenas.size();i++){
                        if(listaEscenas.get(i)!=n){
                                numNivel[j]=listaEscenas.get(i).getNumero();
                                j++;
                        }
                }
                return numNivel;
        }
        
        /**
         * Establece un evento de tipo conexión
         * @param n
         * @return
         */
        public Nivel crearConexion(int n){
                return listaEscenas.get(n);
        }
        
        /* *********************************************************************************************
         * En esta parte tenemos los métodos para poder ejecutar el juego.
         * Los anteriores son mayormente para crearlos, aunque los set & get sirven para ambos.
         * *********************************************************************************************
         */
        
        /**
         * Devuelve el nivel inicial de 
         * @return
         */
        public Nivel iniciar(){
                return listaEscenas.get(0);
        }

        /**
         * Devuelve el nivel 
         * @param n Id del siguiente nivel
         * @return      Devuelve el nivel indicado en el evento.
         */
        public Nivel siguienteNivel(int n){
                for(int i=0;i<listaEscenas.size();i++){
                        if(n==listaEscenas.get(i).getNumero()){
                                return listaEscenas.get(i);
                        }
                }
                return iniciar();
        }
        
        public Nivel obtenerNiveles(int n){
                return listaEscenas.get(n);
        }

        /**
         * Devuelve la lista de niveles. Estos datos deben ser utilizados solo de lectura.
         * @return Lista de escenas.
         */
        public ArrayList<Nivel> getNiveles() {
                return listaEscenas;
        }

}